﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WhittleList.Bll;
using WhittleList.Tests.Helpers;

namespace WhittleList.Tests.Bll
{
    [TestClass]
    public class UserTests
    {
        [TestMethod]
        public void User_IdSignatureTest()
        {
            var prop = typeof(User).GetProperty("Id");
            Assert.IsNotNull(prop);
            prop.AssertReadyOnly();
            prop.AssertInt();
        }

        [TestMethod]
        public void User_FirstNameSignatureTest()
        {
            var prop = typeof(User).GetProperty("FirstName");
            Assert.IsNotNull(prop);
            prop.AssertReadyWrite();
            prop.AssertString();
        }

        [TestMethod]
        public void User_LastNameSignatureTest()
        {
            var prop = typeof(User).GetProperty("LastName");
            Assert.IsNotNull(prop);
            prop.AssertReadyWrite();
            prop.AssertString();
        }

        [TestMethod]
        public void User_EmailAddressSignatureTest()
        {
            var prop = typeof(User).GetProperty("EmailAddress");
            Assert.IsNotNull(prop);
            prop.AssertReadyWrite();
            prop.AssertString();
        }

        [TestMethod]
        public void User_CIDSignatureTest()
        {
            var prop = typeof(User).GetProperty("CID");
            prop.AssertReadyOnly();
            prop.AssertBinary();
        }

        [TestMethod]
        public void User_DisplayNameSignatureTest()
        {
            var prop = typeof(User).GetProperty("DisplayName");
            prop.AssertReadyOnly();
            prop.AssertString();
        }

        [TestMethod]
        public void User_IsValidSignatureTest()
        {
            var prop = typeof(User).GetProperty("IsValid");
            prop.AssertReadyOnly();
            prop.AssertBool();
        }

        [TestMethod]
        public void User_CreatedSignatureTest()
        {
            var prop = typeof(User).GetProperty("Created");
            prop.AssertReadyOnly();
            prop.AssertDateTime();
        }
        [TestMethod]
        public void User_LastUpdatedSignatureTest()
        {
            var prop = typeof(User).GetProperty("LastUpdated");
            prop.AssertReadyOnly();
            prop.AssertDateTime();
        }

        [TestMethod]
        public void User_LastLoggedInSignatureTest()
        {
            var prop = typeof(User).GetProperty("LastLoggedIn");
            prop.AssertReadyOnly();
            prop.AssertNullableDateTime();
        }

        [TestMethod]
        public void User_DisplayNameTest()
        {
            User user = new User();
            user.FirstName = "Display";
            user.LastName = "Name";
            Assert.AreEqual("Display Name", user.DisplayName);
        }

        [TestMethod]
        public void User_AuthenticatePassword_CorrectPassword_ResturnsTrue()
        {
            User user = new User();
            user.SetPassword("password", null);
            Assert.IsTrue(user.AuthenticatePassword("password"));
        }

        [TestMethod]
        public void User_AuthenticatePassword_InCorrectPassword_ResturnsFalse()
        {
            User user = new User();
            user.SetPassword("password", null);
            Assert.IsFalse(user.AuthenticatePassword("error"));
        }

        [TestMethod]
        public void User_FirstName_Required()
        {
            var user = new User();
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "FirstName").Count());
            user.FirstName = "Test";
            Assert.AreEqual(0, user.GetRuleViolations().Where(x => x.PropertyName == "FirstName").Count());
        }

        [TestMethod]
        public void User_LastName_Required()
        {
            var user = new User();
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "LastName").Count());
            user.LastName = "Test";
            Assert.AreEqual(0, user.GetRuleViolations().Where(x => x.PropertyName == "LastName").Count());
        }

        [TestMethod]
        public void User_EmailAddress_Required()
        {
            var user = new User();
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "EmailAddress").Count());
            user.EmailAddress = "email@test.com";
            Assert.AreEqual(0, user.GetRuleViolations().Where(x => x.PropertyName == "EmailAddress").Count());
        }

        [TestMethod]
        public void User_EmailAddress_InvalidFormat()
        {
            var user = new User();
            user.EmailAddress = "rubbish";
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "EmailAddress").Count());
            user.EmailAddress = "email@test.com";
            Assert.AreEqual(0, user.GetRuleViolations().Where(x => x.PropertyName == "EmailAddress").Count());
        }

        [TestMethod]
        public void User_SetPassword_WithEmptyString_CauseRuleViolation()
        {
            var user = new User();
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "Password").Count());
            user.SetPassword("", null);
            Assert.AreEqual(1, user.GetRuleViolations().Where(x => x.PropertyName == "Password").Count());
        }

    }
}
